package arcturus;

//Written by travis Anderson, dont ask me how i did this i just saw the code in my head :-P

import java.util.HashMap;

import java.util.Map.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.List;
import java.util.ListIterator;
import java.util.Properties;
import java.util.Set;

import acm.graphics.GObject;

public class HashVectorMapVer2<K, V> extends HashMap<K, V> {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private HashMap<String, Integer> map;	
	private Properties objtList;
	

	// ====================================
	public HashVectorMapVer2() {
		super();
		this.objtList = new Properties();
		this.map = new HashMap<String, Integer>();
	}
	//====================================
	
	//==============================

	// ====================================
	public V put(K key, V value) {
		super.put(key, value);
		return value;
	}

	// ====================================
	public V put(K key, V value, int x1, int x2, int y1, int y2) throws Exception {
		if (x1 <= x2 && y1 <= y2) {
			super.put(key, value);
			mapAll(value, x1, x2, y1, y2);
			//mapAllY(value, y1, y2);
		} else {
			throw new Exception(
					"Game Error in Collition Detection\r\nx1 or y1 needs to be less than x2 or y2\r\nValues: x1:"
							+ x1 + " x2:" + x2 + " y1:" + y1 + " y2:" + y2);
		}

		return value;
	}

	// ====================================
	private void mapAll(V value, int x1, int x2, int y1, int y2) {
		int hash = value.hashCode();		
		this.objtList.put(hash, value);
		for(int x = y1; x <= y2; x++){
			for (int i = x1; i <= x2; i++) {							
					this.map.put(combineXY(i, x), hash);				
			}
		}			
	}

	// ====================================
	// ====================================

	public V remove(Object key) {
		V rval = this.get(key);		
		super.remove(key);
		this.removeMappings(rval);
		//this.removeYmappings(rval);
		return rval;
	}

	// ====================================
	private void removeMappings(V val){		
		int hash = val.hashCode();
		this.objtList.remove(hash);
		List<Entry<String, Integer>> remove = new ArrayList<Entry<String, Integer>>();
		Set<Entry<String, Integer>> e = map.entrySet();
		
		for (Entry<String, Integer> ex : e) {				
			if(((int)ex.getValue()) == hash){
				remove.add(ex);
			}
		}
		this.map.remove(remove);
	}

	private void debugoutput(List<Entry<Object, Object>> l){
		
		for(Entry<Object, Object> ex : l){
			System.out.print(ex.getKey()+" ");	
			//xmap.remove(Integer.valueOf(ex.getKey().toString()));
		}
		System.out.println();
		
	}
		
	// ====================================
	public boolean isColliding(int x, int y) {
		boolean rval = false;			
		System.out.println(x+" "+y);
		System.out.println(combineXY(x, y));
		rval=this.map.containsKey(combineXY(x, y));			
		return rval;
	}
	// ====================================
		

	// ====================================
	public V getValueAt(int x, int y) {		
		V rval = null;
		int hash = 0;		
		if(this.map.containsKey(combineXY(x, y))){		
				hash = this.map.get(combineXY(x, y));
				rval = (V) this.objtList.get(hash);		
				System.out.println(rval);
		}		
		
		return rval;
	}
	// ====================================
	private String combineXY(int x, int y){
		StringBuilder sb = new StringBuilder();
		sb.append(x);
		sb.append(y);
		return sb.toString();
	}
}
